package com.luobr.backend.controller;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.luobr.backend.annotation.AuthCheck;
import com.luobr.backend.api.aliyunai.AliYunAiApi;
import com.luobr.backend.api.aliyunai.model.CreateImageSynthesisTaskResponse;
import com.luobr.backend.api.aliyunai.model.GetImageSynthesisTaskResponse;
import com.luobr.backend.api.imageSearch.ImageSearchApiFacade;
import com.luobr.backend.constant.SpaceUserConstant;
import com.luobr.backend.manage.auth.SpaceUserAuthManager;
import com.luobr.backend.manage.auth.StpKit;
import com.luobr.backend.model.entity.Space;
import com.luobr.backend.model.vo.image.ImageSearchResultVO;
import com.luobr.backend.common.BaseResponse;
import com.luobr.backend.common.ResponseCode;
import com.luobr.backend.common.ResultUtils;
import com.luobr.backend.constant.UserConstant;
import com.luobr.backend.exception.ThrowUtils;
import com.luobr.backend.model.dto.image.*;
import com.luobr.backend.model.entity.Image;
import com.luobr.backend.model.entity.User;
import com.luobr.backend.model.enums.ReviewStatusEnum;
import com.luobr.backend.model.vo.image.ImageTagCategoryVO;
import com.luobr.backend.model.vo.image.ImageVO;
import com.luobr.backend.model.vo.user.UserLoginVO;
import com.luobr.backend.service.ImageService;
import com.luobr.backend.service.SpaceService;
import com.luobr.backend.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;

/**
 * @author 罗念笙
 * @date 2025/2/23 17:09
 */
@Slf4j
@RestController
@RequestMapping("/image")
public class ImageController {

    @Resource
    private UserService userService;
    @Resource
    private ImageService imageService;
    @Resource
    private AliYunAiApi aliYunAiApi;
    @Resource
    private SpaceUserAuthManager spaceUserAuthManager;
    @Resource
    @Lazy
    private SpaceService spaceService;

    /**
     * 上传图片（可重新上传）
     */
    @PostMapping("/upload")
    public BaseResponse<ImageVO> uploadImage(MultipartFile multipartFile,
                                             ImageUploadRequest imageUploadRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(ObjUtil.isNull(imageUploadRequest), ResponseCode.PARAMS_ERROR);
        UserLoginVO loginUser = userService.getLoginUser(request);
        ImageVO imageVO = imageService.uploadImage(multipartFile, imageUploadRequest, loginUser);
        return ResultUtils.success(imageVO);
    }

    /**
     * 通过 URL 上传图片（可重新上传）
     */
    @PostMapping("/upload/url")
    public BaseResponse<ImageVO> uploadImageByUrl(
            @RequestBody ImageUploadRequest imageUploadRequest,
            HttpServletRequest request) {
        UserLoginVO loginUser = userService.getLoginUser(request);
        String fileUrl = imageUploadRequest.getFileUrl();
        ImageVO imageVO = imageService.uploadImage(fileUrl, imageUploadRequest, loginUser);
        return ResultUtils.success(imageVO);
    }

    /**
     * 批量生成图片
     */
    @PostMapping("/upload/batch")
    @AuthCheck(roleValue = UserConstant.USER_ROLE.ADMIN)
    public BaseResponse<Integer> uploadImageByBatch(@RequestBody ImageUploadByBatchRequest imageUploadByBatchRequest,
                                                    HttpServletRequest request) {
        ThrowUtils.throwIf(ObjUtil.isNull(imageUploadByBatchRequest), ResponseCode.PARAMS_ERROR);
        UserLoginVO loginUser = userService.getLoginUser(request);
        int uploadCount = imageService.uploadImageByBatch(imageUploadByBatchRequest, loginUser);
        return ResultUtils.success(uploadCount);
    }

    /**
     * 删除图片
     */
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteImage(long id, HttpServletRequest request) {
        // 校验参数
        ThrowUtils.throwIf(id <= 0, ResponseCode.PARAMS_ERROR);
        UserLoginVO loginUser = userService.getLoginUser(request);
        imageService.deleteImage(id, loginUser);
        return ResultUtils.success(true);
    }

    /**
     * 编辑图片（仅限本人管理员权限）
     */
    @PostMapping("/edit")
    public BaseResponse<Boolean> editImage(@RequestBody ImageEditRequest imageEditRequest, HttpServletRequest request) {
        // 校验参数
        ThrowUtils.throwIf(ObjUtil.isNull(imageEditRequest) || imageEditRequest.getId() <= 0, ResponseCode.PARAMS_ERROR);
        UserLoginVO loginUser = userService.getLoginUser(request);
        imageService.editImage(imageEditRequest, loginUser);
        return ResultUtils.success(true);
    }

    /**
     * 更新图片（仅限管理员权限）
     */
    @PostMapping("/update")
    @AuthCheck(roleValue = UserConstant.USER_ROLE.ADMIN)
    public BaseResponse<Boolean> updateImage(@RequestBody ImageUpdateRequest imageUpdateRequest, HttpServletRequest request) {
        // 校验参数
        ThrowUtils.throwIf(imageUpdateRequest == null || imageUpdateRequest.getId() <= 0, ResponseCode.PARAMS_ERROR);
        // 转换成图片实体
        Image image = ImageUpdateRequest.dtoToObj(imageUpdateRequest);
        // 校验图片信息
        imageService.validImage(image);
        // 校验原图片是否存在
        Image oldImage = imageService.getById(imageUpdateRequest.getId());
        ThrowUtils.throwIf(ObjUtil.isNull(oldImage), ResponseCode.OPERATION_ERROR, "更新图片失败！");
        // 修改图片审核信息
        UserLoginVO loginUser = userService.getLoginUser(request);
        imageService.filterReviewImage(image, loginUser);
        // 更新图片
        boolean result = imageService.updateById(image);
        ThrowUtils.throwIf(!result, ResponseCode.OPERATION_ERROR, "更新图片失败！");
        return ResultUtils.success(true);
    }

    /**
     * 通过图片 id 获取脱敏后的图片信息
     */
    @PostMapping("/get/vo")
    public BaseResponse<ImageVO> getImageVOById(long id, HttpServletRequest request) {
        // 校验参数
        ThrowUtils.throwIf(id <= 0, ResponseCode.PARAMS_ERROR);
        // 获取审核通过的图片和用户信息
        Image image = imageService.getOne(new QueryWrapper<Image>().eq("id", id).
                eq("reviewStatus", ReviewStatusEnum.PASS.getValue()));
        ThrowUtils.throwIf(ObjUtil.isNull(image), ResponseCode.PARAMS_ERROR);
        // 校验权限
        UserLoginVO loginUser = userService.getLoginUser(request);
        // imageService.checkImageAndSpaceAuth(loginUser, image);
        Space space = null;
        Long spaceId = image.getSpaceId();
        if (spaceId != null) {
            boolean hasPermission = StpKit.SPACE.hasPermission(SpaceUserConstant.SpaceUserPermission.IMAGE_VIEW);
            ThrowUtils.throwIf(!hasPermission, ResponseCode.NO_AUTH_ERROR);
            space = spaceService.getById(spaceId);
            ThrowUtils.throwIf(space == null, ResponseCode.NOT_FOUND_ERROR, "空间不存在");
        }
        // 查询用户信息
        User user = userService.getOne(new QueryWrapper<User>().eq("id", image.getUserId()));
        // 设置图片的权限列表
        ImageVO imageVO = ImageVO.objToVo(image, UserLoginVO.objToLoginVo(user));
        List<String> permissionList = spaceUserAuthManager.getPermissionList(space, loginUser);
        imageVO.setPermissionList(permissionList);
        // 图片信息添加用户信息
        return ResultUtils.success(imageVO);
    }

    /**
     * 通过图片 id 获取脱敏后的图片信息
     */
    @PostMapping("/get")
    @AuthCheck(roleValue = UserConstant.USER_ROLE.ADMIN)
    public BaseResponse<Image> getImageById(long id) {
        // 校验参数
        ThrowUtils.throwIf(id <= 0, ResponseCode.PARAMS_ERROR);
        // 获取图片和用户信息
        Image image = imageService.getById(id);
        ThrowUtils.throwIf(image == null, ResponseCode.PARAMS_ERROR);
        // 图片信息添加用户信息
        return ResultUtils.success(image);
    }

    /**
     * 获取脱敏后的图片信息分页数据
     */
    @PostMapping("/list/page/vo")
    public BaseResponse<Page<ImageVO>> listImageVOByPage(@RequestBody ImageQueryRequest imageQueryRequest, HttpServletRequest request) {
        // 校验参数
        ThrowUtils.throwIf(ObjUtil.isNull(imageQueryRequest), ResponseCode.PARAMS_ERROR);
        // 普通用户只能查询到审核通过的图片数据
        imageQueryRequest.setReviewStatus(ReviewStatusEnum.PASS.getValue());
        // 返回分页数据
        UserLoginVO loginUser = userService.getLoginUser(request);
        return ResultUtils.success(imageService.getImageVOPage(imageQueryRequest, loginUser));
    }

    /**
     * 获取脱敏后的图片信息分页数据
     */
    @PostMapping("/list/page")
    @AuthCheck(roleValue = UserConstant.USER_ROLE.ADMIN)
    public BaseResponse<Page<Image>> listImageByPage(@RequestBody ImageQueryRequest imageQueryRequest) {
        // 校验参数
        ThrowUtils.throwIf(ObjUtil.isNull(imageQueryRequest), ResponseCode.PARAMS_ERROR);
        // 获取分页条件
        int current = imageQueryRequest.getCurrent();
        int pageSize = imageQueryRequest.getPageSize();
        // 获取到分页数据
        Page<Image> imagePage = imageService.page(new Page<>(current, pageSize), imageService.getQueryWrapper(imageQueryRequest));
        // 返回分页数据
        return ResultUtils.success(imagePage);
    }

    /**
     * 图像标签列表
     */
    @GetMapping("/list/tagCategory")
    public BaseResponse<ImageTagCategoryVO> listImageTagCategory() {
        ImageTagCategoryVO imageTagCategoryVO = new ImageTagCategoryVO();
        // TODO: 暂时定死（随着系统规模和数据不断扩大，可以再改为使用配置中心或数据库动态管理这些数据，或者通过定时任务计算出热门的图片分类和标签）
        imageTagCategoryVO.setTagList(Arrays.asList("热门", "背景", "简历", "创意"));
        imageTagCategoryVO.setCategoryList(Arrays.asList("模板", "电商", "表情包"));
        return ResultUtils.success(imageTagCategoryVO);
    }

    /**
     * 审核图片信息
     */
    @PostMapping("/review")
    @AuthCheck(roleValue = UserConstant.USER_ROLE.ADMIN)
    public BaseResponse<Boolean> reviewImage(@RequestBody ImageReviewRequest imageReviewRequest,
                                             HttpServletRequest request) {
        ThrowUtils.throwIf(ObjUtil.isNull(imageReviewRequest), ResponseCode.PARAMS_ERROR);
        UserLoginVO loginUser = userService.getLoginUser(request);
        imageService.reviewImage(imageReviewRequest, loginUser);
        return ResultUtils.success(true);
    }

    /**
     * 以图搜图
     */
    @PostMapping("/search")
    public BaseResponse<List<ImageSearchResultVO>> searchImage(@RequestBody ImageSearchRequest imageSearchRequest) {
        ThrowUtils.throwIf(imageSearchRequest == null, ResponseCode.PARAMS_ERROR);
        Long imageId = imageSearchRequest.getImageId();
        ThrowUtils.throwIf(imageId == null, ResponseCode.PARAMS_ERROR);
        Image imageDB = imageService.getById(imageId);
        ThrowUtils.throwIf(imageDB == null, ResponseCode.NOT_FOUND_ERROR);
        List<ImageSearchResultVO> resultList = ImageSearchApiFacade.searchImage(imageDB.getUrl());
        return ResultUtils.success(resultList);
    }

    /**
     * 创建 AI 扩图任务
     */
    @PostMapping("/createImageSynthesisTask")
    public BaseResponse<CreateImageSynthesisTaskResponse> createImageTask(
            @RequestBody CreateImageTaskRequest createImageTaskRequest, HttpServletRequest request) {
        // 校验参数
        ThrowUtils.throwIf(createImageTaskRequest == null || createImageTaskRequest.getImageId() == null, ResponseCode.PARAMS_ERROR);
        UserLoginVO loginUser = userService.getLoginUser(request);
        return ResultUtils.success(imageService.createImageSynthesisTask(createImageTaskRequest, loginUser));
    }

    /**
     * 查询 AI 扩图任务
     */
    @GetMapping("/getImageSynthesisTask")
    public BaseResponse<GetImageSynthesisTaskResponse> getImageTask(String taskId) {
        // 校验参数
        ThrowUtils.throwIf(StrUtil.isBlank(taskId), ResponseCode.PARAMS_ERROR);
        return ResultUtils.success(aliYunAiApi.getOutPaintingTask(taskId));
    }
}